package com.pilipili.serverapi.controller.manageUser;

import com.pilipili.common.Exception.BusinessRuntimeException;
import com.pilipili.common.controller.AbstractController;
import com.pilipili.common.controller.PageCommResult;
import com.pilipili.serverapi.ErrorCode;
import com.pilipili.serverapi.config.ShiroConfig;
import com.pilipili.serverapi.manageUser.dto.req.AssignPermissionsDto;
import com.pilipili.serverapi.manageUser.dto.req.RoleDto;
import com.pilipili.serverapi.manageUser.dto.req.RoleWithIdDto;
import com.pilipili.serverapi.manageUser.dto.resp.PermissionWithCreateTimeDto;
import com.pilipili.serverapi.manageUser.dto.resp.RoleWithCreateTimeDto;
import com.pilipili.serverapi.manageUser.entity.Permission;
import com.pilipili.serverapi.manageUser.entity.Role;
import com.pilipili.serverapi.manageUser.service.PermissionService;
import com.pilipili.serverapi.manageUser.service.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * 角色管理接口
 *
 * @author chen.guosheng
 */
@Api(description = "角色管理接口")
@RestController
@RequestMapping("/serverapi/role")
public class RoleController extends AbstractController {

    private static final Logger LOG = LoggerFactory.getLogger(ManageUserController.class);

    @Autowired
    private RoleService roleService;
    @Autowired
    private PermissionService permissionService;

    @ApiOperation(value = "新增角色")
    @ApiImplicitParam(name="Token", value="用于验证登录的token", paramType="header",dataType="string")
    @RequiresPermissions("roleManage")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public PageCommResult<Object> add(@Valid @RequestBody RoleDto roleDto, BindingResult bindingResult) {
        LOG.info(" access /serverapi/role/add roleDto {} ", roleDto);
        if (bindingResult.hasErrors()) {
            throw new BusinessRuntimeException(ErrorCode.PRAMERROR.getCode(),
                    bindingResult.getFieldError().getDefaultMessage());
        }
        if(roleService.exits("roleName", roleDto.getRoleName(), Role.class)){
            throw new BusinessRuntimeException(ErrorCode.ROLE_EXITS);
        }
        Role role = new Role();
        BeanUtils.copyProperties(roleDto, role);
        roleService.save(role);
        ShiroConfig.clearCache();
        return this.successPageResultWithEmptyResult();
    }

    @ApiOperation(value = "编辑角色")
    @ApiImplicitParam(name="Token", value="用于验证登录的token", paramType="header",dataType="string")
    @RequiresPermissions("roleManage")
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public PageCommResult<Object> edit(@Valid @RequestBody RoleWithIdDto roleWithIdDto,
                                       BindingResult bindingResult) {
        LOG.info(" access /serverapi/role/edit roleWithIdDto {} ", roleWithIdDto);
        if (bindingResult.hasErrors()) {
            throw new BusinessRuntimeException(ErrorCode.PRAMERROR.getCode(),
                    bindingResult.getFieldError().getDefaultMessage());
        }
        roleService.editAfterFind(roleWithIdDto.getId(), roleWithIdDto, ErrorCode.ROLE_NOT_FOUND);
        ShiroConfig.clearCache();
        return this.successPageResultWithEmptyResult();
    }

    @ApiOperation(value = "搜索角色")
    @ApiImplicitParam(name="Token", value="用于验证登录的token", paramType="header",dataType="string")
    @RequiresPermissions("roleManage")
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public PageCommResult<RoleWithCreateTimeDto> search(@RequestParam(value = "roleName", defaultValue = "") String roleName,
                                                        @RequestParam(value = "currentPage", defaultValue = "0") Integer currentPage,
                                                        @RequestParam(value = "pageCount", defaultValue = "10") Integer pageCount) {
        LOG.info(" access /serverapi/role/search roleName {} start {} count {} ", roleName, currentPage, pageCount);
        return roleService.search(roleName, currentPage, pageCount);
    }

    @ApiOperation(value = "批量删除角色")
    @ApiImplicitParam(name="Token", value="用于验证登录的token", paramType="header",dataType="string")
    @RequiresPermissions("roleManage")
    @RequestMapping(value = "/batchDelete", method = RequestMethod.POST)
    public PageCommResult<Object> batchDelete(@RequestParam("roleIds")List<Long> roleIds) {
        LOG.info(" access /serverapi/role/batchDelete roleIds {} ", roleIds);
        roleService.batchDelete(roleIds);
        ShiroConfig.clearCache();
        return this.successPageResultWithEmptyResult();
    }

    @ApiOperation(value = "分配权限")
    @ApiImplicitParam(name="Token", value="用于验证登录的token", paramType="header",dataType="string")
    @RequiresPermissions("roleManage")
    @RequestMapping(value = "/assignPermissions", method = RequestMethod.POST)
    public PageCommResult<Object> assignPermissions(@Valid @RequestBody AssignPermissionsDto assignPermissionsDto, BindingResult bindingResult) {
        LOG.info(" access /serverapi/role/assignPermissions assignPermissionsDto {} ", assignPermissionsDto);
        if (bindingResult.hasErrors()) {
            throw new BusinessRuntimeException(ErrorCode.PRAMERROR.getCode(),
                    bindingResult.getFieldError().getDefaultMessage());
        }
        List<Permission> permissions = this.permissionService.findByIdIn(assignPermissionsDto.getPermissionIds());
        this.roleService.assignPermissions(assignPermissionsDto.getRoleId(), permissions);
        ShiroConfig.clearCache();
        return this.successPageResultWithEmptyResult();
    }

    @ApiOperation(value = "根据角色id获取权限")
    @ApiImplicitParam(name="Token", value="用于验证登录的token", paramType="header",dataType="string")
    @RequiresPermissions("roleManage")
    @RequestMapping(value = "/getPermissionsByRole", method = RequestMethod.GET)
    public PageCommResult<PermissionWithCreateTimeDto> getPermissionsByRole(@RequestParam("roleId") Long roleId,
                                                                            @RequestParam(value = "currentPage", defaultValue = "0") Integer currentPage,
                                                                            @RequestParam(value = "pageCount", defaultValue = "10") Integer pageCount) {
        LOG.info(" access /serverapi/role/getPermissionsByRole roleId {} ", roleId);
        List<Role> roles = new ArrayList<Role>();
        roles.add(this.roleService.find(roleId));
        return this.permissionService.findByRoles(roles, currentPage, pageCount);
    }

    @ApiOperation(value = "验证角色管理权限")
    @ApiImplicitParam(name="Token", value="用于验证登录的token", paramType="header",dataType="string")
    @RequiresPermissions("roleManage")
    @RequestMapping(value = "/testAuth", method = RequestMethod.POST)
    public PageCommResult<Object> testAuth() {
        LOG.info(" access /serverapi/role/testAuth");
        return this.successPageResultWithEmptyResult();
    }
}
